package com.fangxing.module.user.service;

import com.fangxing.config.SysCfgParam;
import com.fangxing.module.user.bo.LoginBo;
import com.fangxing.module.user.bo.RegisterBo;
import com.fangxing.module.user.dao.AccountRepository;
import com.fangxing.module.user.entity.AccountEntity;
import com.fangxing.util.RandomCodeGenerator;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.UUID;

@Service
public class AccountService {
    @Autowired
    private AccountRepository accountRepository;

    public boolean register(RegisterBo registerBo) {
        if (registerBo.getPassword().equals(registerBo.getRepassword()) == false) {
            return false;
        }

        if (StringUtils.isEmpty(registerBo.getCellphone()) && StringUtils.isEmpty(registerBo.getUsername())) {
            return false;
        }

        String salt = getSalt();
        AccountEntity entity = new AccountEntity();
        entity.setActive(true);
        entity.setCellphone(registerBo.getCellphone());
        entity.setUsername(registerBo.getUsername());
        entity.setSalt(salt);
        entity.setPassword(encryptPassword(entity.getPassword(), salt));

        if (save(entity) == null) {
            return false;
        }

        return true;
    }



    public AccountEntity findAccountByString(String str) {
        if (com.fangxing.util.StringUtils.isPhoneNo(str)) {
            return accountRepository.findByCellphone(str);
        } else if ((com.fangxing.util.StringUtils.isEmail(str))) {
            return accountRepository.findByEmail(str);
        } else {
            return accountRepository.findByUsername(str);
        }
    }

    public AccountEntity checkAccount(String name, String pwd) {
        AccountEntity entity = findAccountByString(name);
        if (entity == null || entity.getActive() == false) {
            return null;
        }

        if (matchPassword(entity, pwd)){
            return entity;
        }

        return null;
    }


    private boolean matchPassword(AccountEntity entity, String pwd) {
        String encryptPwd = encryptPassword(pwd, entity.getSalt());
        return encryptPwd.equals(entity.getPassword());
        }

    public boolean isUsedUsername(String username) {
        if (StringUtils.isEmpty(username) == false && accountRepository.findByUsername(username) != null) {
            return true;
        }

        return false;
    }

    public boolean isUsedEmail(String email) {
        if (StringUtils.isEmpty(email) == false && accountRepository.findByUsername(email) != null) {
            return true;
        }

        return false;
    }

    public boolean isUsedPhoneNo(String phoneNo) {
        if (StringUtils.isEmpty(phoneNo) == false && accountRepository.findByUsername(phoneNo) != null) {
            return true;
        }

        return false;
    }


    public boolean isExistAccount(String username, String email, String cellphone){
        //需要优化
        if (isUsedPhoneNo(cellphone)
                || isUsedUsername(username)
                || isUsedEmail(email)) {
            return true;
        }

        return false;
    }

    @Transactional
    public AccountEntity save(AccountEntity entity) {
        if (isExistAccount(entity.getUsername(), entity.getEmail(), entity.getCellphone())) {
            return null;
        }

        entity = accountRepository.save(entity);
        return entity;
    }

    private String getSalt() {
        return UUID.randomUUID().toString();
    }

    private String encryptPassword(String password, String salt) {
        return digest(password, salt).toString();
    }

    private String digest(String password, String salt){
        try {
            MessageDigest msgDigest = MessageDigest.getInstance("SHA");
            if (StringUtils.isEmpty(salt)) {
                msgDigest.update(salt.getBytes());
            }

            String digest = msgDigest.digest(password.getBytes()).toString();
            return digest;
        } catch (NoSuchAlgorithmException e) {
            return null;
        }
    }

}
